package com.fastfly.domain;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.springframework.validation.Errors;

@Table(name = "Users")
@Entity
public class Customer extends BaseEntity {

	private static final long serialVersionUID = 1L;

	@Column(name = "username")
	protected String flyNumber;
	protected String firstName, lastName, address1, address2, city, state, zip, phone, email, password;
	
	protected int milesAccumulated = 5000;

	protected short enabled = 1;

	@ManyToOne(cascade = CascadeType.ALL)
	protected Authority authority = new Authority();
	
	@ManyToOne
	protected SecurityQuestion question;
	
	protected String securityAnswer;
	
	
	@OneToMany (mappedBy="customer")
	protected List<Reservation> reservationCollection = new ArrayList<Reservation>();
	
	@Transient
	protected String confirmPwd;
	

	public Authority getAuthority() {
		return authority;
	}

	public void setAuthority(Authority authority) {
		this.authority = authority;
		authority.setUsername(this.getFlyNumber());
	}

	public String getFlyNumber() {
		return flyNumber;
	}

	/**
	 * @param flyNumber
	 *            the flyNumber to set
	 */
	public void setFlyNumber(String flyNumber) {
		this.flyNumber = flyNumber;
		authority.setUsername( flyNumber );
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getAddress1() {
		return address1;
	}

	public void setAddress1(String address1) {
		this.address1 = address1;
	}

	public String getAddress2() {
		return address2;
	}

	public void setAddress2(String address2) {
		this.address2 = address2;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}

	public String getZip() {
		return zip;
	}

	public void setZip(String zip) {
		this.zip = zip;
	}

	/**
	 * @return the phone
	 */
	public String getPhone() {
		return phone;
	}

	/**
	 * @param phone
	 *            the phone to set
	 */
	public void setPhone(String phone) {
		this.phone = phone;
	}

	/**
	 * @return the email
	 */
	public String getEmail() {
		return email;
	}

	/**
	 * @param email
	 *            the email to set
	 */
	public void setEmail(String email) {
		this.email = email;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}	
	

	public SecurityQuestion getQuestion() {
		return question;
	}

	public void setQuestion(SecurityQuestion question) {
		this.question = question;
	}

	public String getSecurityAnswer() {
		return securityAnswer;
	}

	public void setSecurityAnswer(String securityAnswer) {
		this.securityAnswer = securityAnswer;
	}

	public short getEnabled() {
		return enabled;
	}

	public void setEnabled(short enabled) {
		this.enabled = enabled;
	}

	/**
	 * @return the confirmPwd
	 */
	public String getConfirmPwd() {
		return confirmPwd;
	}	
	

	public int getMilesAccumulated() {
		return milesAccumulated;
	}

	public void setMilesAccumulated(int milesAccumulated) {
		this.milesAccumulated = milesAccumulated;
	}

	/**
	 * @param confirmPwd
	 *            the confirmPwd to set
	 */
	public void setConfirmPwd(String confirmPwd) {
		this.confirmPwd = confirmPwd;
	}

	public void enroll() {
		generateFlightNumber();
		milesAccumulated = 5000;
	}
	
	protected void generateFlightNumber() {
		flyNumber = lastName.substring(0, 2).toUpperCase() + Math.abs(random.nextInt() % 9999999);
		authority.setUsername(flyNumber);
	}

	/*
	public void validateCustomerForm(ValidationContext context) {
		MessageContext messages = context.getMessageContext();
		if ( password == null || confirmPwd == null ) {			
			messages.addMessage(new MessageBuilder().error().defaultText("Password or Confirm Password cannot be null!").build());
		} else if (! password.equals(confirmPwd)) {			
			messages.addMessage(new MessageBuilder().error().defaultText("Password does not match!").build());
		} 
		
		if (lastName.length() < 2) {
			messages.addMessage(new MessageBuilder().error().defaultText("Last name needs to be greater than 1 character!").build());			
		}
	}
	*/
	
	public void validateCustomerForm(Errors errors) {		
		validatePassword(errors); 		
		if (lastName.length() < 2) {
			errors.rejectValue("lastName", "", "Last name needs to be greater than 1 character!");			
		}
	}

	public void validatePassword(Errors errors) {
		if ( password == null || confirmPwd == null ) {
			errors.rejectValue("password", "", "Password or Confirm Password cannot be null!");			
		} else if (! password.equals(confirmPwd)) {			
			errors.rejectValue("password", "", "Password does not match!");			
		}
	}
	
	public void addReservation(Reservation reservation) {
		for (Ticket ticket : reservation.getTicketCollection()) {
			if ( Reservation.PAYMENT_TYPE_CREDIT_CARD.equalsIgnoreCase(reservation.getPaymentType())  ) {
				milesAccumulated += ticket.getSeatInDepartureFlight().getFlight().getFlightMiles();			
				milesAccumulated += ticket.getSeatInReturnFlight().getFlight().getFlightMiles();				
			} else {
				milesAccumulated -= Reservation.MILES_NEED_PER_ROUNDTRIP_TICKET;				
			}			
		}		 
		reservationCollection.add(reservation);		
	}

	public List<Reservation> getReservationCollection() {
		return reservationCollection;
	}
	
	

}
